package com.study.core.security;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.*;
import org.springframework.security.access.vote.RoleHierarchyVoter;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * spring security第三步：验证权限
 * Created by think on 2016/4/24.
 */
public class MyAccessDecisionManager implements AccessDecisionManager {
    public static Logger logger = LoggerFactory.getLogger(MyAccessDecisionManager.class);

    private List<RoleHierarchyVoter> decisionVoters;

    //检查用户是否够权限访问资源
    //参数authentication是从spring的全局缓存SecurityContextHolder中拿到的，里面是用户的权限信息
    //参数object是url
    //参数configAttributes所需的权限
    @Override
    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
        if(configAttributes == null){
           logger.info("configAttributes is null:没有任何菜单和角色的对应");
            return;
        }

        Iterator<ConfigAttribute> ite=configAttributes.iterator();
        while(ite.hasNext()){
            ConfigAttribute ca=ite.next();
            String needRole=((SecurityConfig)ca).getAttribute();
            for(GrantedAuthority ga : authentication.getAuthorities()){
                if(needRole.equals(ga.getAuthority())){
                    return;
                }
            }
        }
        //注意：执行这里，后台是会抛异常的，但是界面会跳转到所配的access-denied-page页面
        throw new AccessDeniedException("当前用户没有访问权限");
    }

    @Override
    public boolean supports(ConfigAttribute configAttribute) {
        return true;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }

    public void setDecisionVoters(List<RoleHierarchyVoter> decisionVoters) {
        this.decisionVoters = decisionVoters;
    }

    public List<RoleHierarchyVoter> getDecisionVoters() {
        return decisionVoters;
    }
}
